/*
 * PhysicalDAO.java
 *
 * Created on March 29, 2007, 9:05 PM
 *
 
 */

package edu.byu.isys413.mystuff.sales;
import edu.byu.isys413.mystuff.*;
import edu.byu.isys413.mystuff.DataException;
import edu.byu.isys413.mystuff.ConnectionPoolException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 *
 * @author Gabe
 */
/** Creates a new instance of PhysicalDAO */
public abstract class PhysicalDAO extends ProductDAO{
    
    ///////////////////////////////////////
    ///   Singleton pattern
    
    private static PhysicalDAO instance = null;
    
    
    public static synchronized PhysicalDAO getInstance(){
        return instance;
    }
    
    
    /////////////////////////////////
    ///   CREATE
    /**
     *
     */
    public abstract PhysicalBO create() throws SQLException, DataException;
    
    //////////////////////////////////////////////////////////////////////////////
    //////////   READ
    /**
     *
     */
    public abstract ProductBO read(String id) throws SQLException, DataException, ConnectionPoolException;
    
    
    public abstract ProductBO readSku(String sku,Connection conn) throws SQLException, DataException;
    /**
     *
     */
    public synchronized ProductBO read(String id, Connection conn) throws SQLException, DataException{
        // check to see if id in the cache
        Cache c = Cache.getInstance();
        //taking the forsalebo and downcasting it to a physical bo
        PhysicalBO phyBO = (PhysicalBO)c.get(id);
        
        //setting up conceptualDAO
//        ConceptualDAO conceptualDAO = ConceptualDAO.getInstance();
        //setting up storeDAO
//        StoreDAO storeDAO = StoreDAO.getInstance();
        //set the conceptual BO to be empty
//        StoreBO storeBO = null;
//        ConceptualBO conceptualBO = null;
        
        //put in cache so super read can have access to it
        c.put(id, phyBO);
        
        //we are calling super.read and passing it the product id...we want it to return a  physicalbo but it will have all the product stuff just hidden
        phyBO = (PhysicalBO)super.read(id, conn);
        
        //now we need to add info from the physical table to the bo we have
        PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM Physical_Product WHERE ProductID =?");
        pstmt.setString(1,id);
        ResultSet rs = pstmt.executeQuery();
        
        String conceptualID="";
        if (rs.next()) {
            //set all of the table info in the "phybo" so we can pass it down to the forsale bo and have access to it
            phyBO.setProductId(rs.getString("ProductID"));
//            conceptualID = (rs.getString("ConceptualProductID"));
            phyBO.setStoreID(rs.getString("StoreID"));
            phyBO.setSerialNumber(rs.getString("SerialNumber"));
            phyBO.setShelfLoc(rs.getString("ShelfLocation"));
            phyBO.setDatePurchased(rs.getString("DatePurchased"));
            phyBO.setSaleOrRent(rs.getString("Sale_Rent"));
            phyBO.setAlreadyInDatabase(true);
            phyBO.setDirty(false);
            System.out.println("reading from physicaldao");
            
            
            //this is calling the conceptual method and sending the conceptual method stored in the physical product table this will allow us
            //read the store product table which will allow us update the QOH etc
//            conceptualBO = (ConceptualBO)conceptualDAO.read(conceptualID,conn);
//            phyBO.setConceptualBO(conceptualBO);
            
            //here is where we access the store information
            //storeBO = storeDAO.read(rs.getString("storeid"));
            //phyBO.setStore(storeBO);
            
            
            // save to the cache
            c.put(phyBO.getProductID(), phyBO);
        }else{
            System.out.println("this is an error");
        }
        
        // return the phyBO to the forsale.dao method
        return phyBO;
    }
    
    /*Retrieve list of all revSrcomers*/
    public abstract ArrayList<ProductBO> readAll() throws SQLException, DataException;
    
    
    
    
    //////////////////////////////////
    ///   UPDATE
    
    /**
     * This is the public save method.  It is what is called when
     * the user (controller) code wants to save or update an object
     * into the database.
     */
    
    
    public void insertPhysical(String id, Connection conn) throws SQLException, DataException{
//        Cache c = Cache.getInstance();
//        PhysicalBO phyBO = (PhysicalBO)c.get(id);
////        super.save(phyBO, conn);
//
//        PreparedStatement pstmt = conn.prepareStatement("INSERT INTO Physical_Product (productid, cproductid, storeid, shelflocation, datepurchased, phystype) VALUES (?, ?, ?, ?, ?, ?)");
//
//        pstmt.setString(1, phyBO.getProductID());
//        pstmt.setString(2, phyBO.getConceptual().getProductID());
//        pstmt.setString(3, phyBO.getStore().getStoreID());
//        pstmt.setString(4, phyBO.getShelfLocation());
//        pstmt.setDate(5, java.sql.Date.valueOf(phyBO.getDatePurchased()));
//        pstmt.setString(6, phyBO.getPhysType());
//
//        pstmt.execute();
//        pstmt.close();
//        phyBO.setAlreadyInDB(true);
//
//        c.put(phyBO.getProductID(), phyBO);
    }
    
    /**
     * This method is really a part of save(bo, conn) above.  It could be
     * embedded directly in it, but I've separated it into it's own method
     * to isolate the SQL udpate statement and make it more readable.  But
     * logically, it's really just a part of save.
     */
    public void update(String id, Connection conn) throws SQLException, DataException{
//        Cache c = Cache.getInstance();
//        PhysicalBO phyBO = (PhysicalBO)c.get(id);
////        super.save(phyBO, conn);
//
//        PreparedStatement pstmt = conn.prepareStatement("UPDATE Physical_product SET productID = ?, CProductID = ?, storeid = ?, shelflocation = ?, datepurchased = ?, phystype = ? WHERE ProductID = ?");
//
//        pstmt.setString(1, phyBO.getProductID());
//        pstmt.setString(2, phyBO.getConceptual().getProductID());
//        pstmt.setString(3, phyBO.getStore().getStoreID());
//        pstmt.setString(4, phyBO.getShelfLocation());
//        pstmt.setDate(5, java.sql.Date.valueOf(phyBO.getDatePurchased()));
//        pstmt.setString(6, phyBO.getPhysType());
//        pstmt.setString(7, phyBO.getProductID());
//
//        pstmt.execute();
//        pstmt.close();
//        phyBO.setAlreadyInDB(true);
//
//        c.put(phyBO.getProductID(), phyBO);
    }
    
    /**
     *
     */
    public abstract void insert(ProductBO bo, Connection conn) throws SQLException, DataException;
    
    ///////////////////////////////////////////////////////////////////////////////
    /////////   DELETE
    
    //I did not include the DELETE functionality intentionally due to instructions received, as well as
    //to protect the integrity of the data.
    
}
